package PrjDBUtils

import (
	db_utils "dgo/goutils/db-utils"
	"dgo/goutils/utils"
	"time"
)

type DBQueueTask struct {
	db_exec_queue *utils.QueueTask
	PopMonitor    *utils.MonitorSpeedNTimeRec
	PushMonitor   *utils.MonitorSpeedNTimeRec
}

func NewDBQueueTask() *DBQueueTask {
	rval := &DBQueueTask{
		db_exec_queue: utils.NewQueueTaskFunc(),
	}
	return rval
}

func (this *DBQueueTask) String() string {
	return this.db_exec_queue.String()
}

func (this *DBQueueTask) ConfigWorkNum(min, max int32) {
	this.db_exec_queue.ConfigWorkNum(min, max)
}

func (this *DBQueueTask) ConfigMaxQueueSize(val int) {
	this.db_exec_queue.ConfigMaxQueueSize(val)
}

func (this *DBQueueTask) ConfigMonitor(enable bool) {
	if enable {
		if this.PopMonitor == nil {
			this.PopMonitor = utils.NewMonitorSpeedNTimeRec()
			utils.Monitor.AddMonitorRec(this.PopMonitor, this.PopMonitor)
		}

		if this.PushMonitor == nil {
			this.PushMonitor = utils.NewMonitorSpeedNTimeRec()
			utils.Monitor.AddMonitorRec(this.PushMonitor, this.PushMonitor)
		}
		this.db_exec_queue.ConfigMonitor(this.PopMonitor, this.PushMonitor)
	} else {
	}

}

func (this *DBQueueTask) PushDBExecQueue(cb func(db *db_utils.DBConn, rec *Db_exec_rec) error) error {
	rec := &Db_exec_rec{WorkCb: cb}
	return this.db_exec_queue.Push(rec)
}

func (this *DBQueueTask) StartDBExecQueueServiceEx(getfn func() *DAOHelper, freefn func(dao *DAOHelper)) {

	this.db_exec_queue.ConfigWorkCallBackCallBackFunc(func(worker *utils.WorkerRec, args ...interface{}) {
		if rec, ok := args[0].(*Db_exec_rec); ok {
			if rec.WorkCb != nil {
				if worker.TagPtr == nil {
					tmpDb := getfn()
					worker.TagPtr = tmpDb
					tmpDb.PrepareDBConn()
				}
				db := worker.TagPtr.(*DAOHelper)
				rec.WorkCb(db.DBConn, rec)
			}
		}
	})
	this.db_exec_queue.ConfigIdleCallBackFunc(func(worker *utils.WorkerRec) {
		if worker.TagPtr != nil {
			if worker.IdleTime() > time.Second || worker.State() == utils.WORKER_STATE_END {
				db := worker.TagPtr.(*DAOHelper)
				freefn(db)
				db.Close()
				worker.TagPtr = nil
			}
		}
	}).Start()
}

func (this *DBQueueTask) StartDBExecQueueService(dbid string) {
	var db_id string = dbid

	this.db_exec_queue.ConfigWorkCallBackCallBackFunc(func(worker *utils.WorkerRec, args ...interface{}) {
		if rec, ok := args[0].(*Db_exec_rec); ok {
			if rec.WorkCb != nil {
				if worker.TagPtr == nil {
					tmpDb, _ := GetDBConn(db_id)
					worker.TagPtr = tmpDb
				}
				db := worker.TagPtr.(*db_utils.DBConn)
				rec.WorkCb(db, rec)
			}
		}
	})
	this.db_exec_queue.ConfigIdleCallBackFunc(func(worker *utils.WorkerRec) {
		if worker.TagPtr != nil {
			if worker.IdleTime() > time.Second || worker.State() == utils.WORKER_STATE_END {
				db := worker.TagPtr.(*db_utils.DBConn)
				db.Close()
				worker.TagPtr = nil
			}
		}
	}).Start()
}
